/*
 * Created by Wildish on 2016-10-28
 *
 * Contact me with keithknight@qq.com
 *
 * Copyright (c) 2016 Wildish
 *
 */

package com.wildish.qcface.activity;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.qcloud.CloudClient;
import com.qcloud.PicCloud;
import com.qcloud.UploadResult;
import com.qcloud.fr.QcloudFrSDK;
import com.tencent.upload.Const;
import com.tencent.upload.UploadManager;
import com.tencent.upload.task.ITask;
import com.tencent.upload.task.IUploadTaskListener;
import com.tencent.upload.task.data.FileInfo;
import com.tencent.upload.task.impl.PhotoUploadTask;
import com.wildish.customprogressdialog.CustomProgressDialog;
import com.wildish.qcface.R;
import com.wildish.qcface.util.FileUtil;
import com.wildish.qcface.util.Global;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

/**
 *
 * Created by Keith on 2016/10/27.
 */
public class RecActivity extends Activity{
    private String photoPath;
    private UploadResult uploadResult;
    private static int RESULT_TAKE_PHOTO = 0;

    private ImageView ivPhoto;
    private TextView tvOutput;

    private UploadManager photoUploadMgr;
    private QcloudFrSDK qcSDK;
    private PicCloud pc;
    private CloudClient cc;
    private CustomProgressDialog dialog;

    private static final int MY_PERMISSIONS_REQUEST_CAMERA = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_rec);
        ivPhoto = (ImageView) findViewById(R.id.iv_photo);
        tvOutput = (TextView) findViewById(R.id.tv_output);

        qcSDK = Global.getQcSDK();
        pc = Global.getPicCloud();
        cc = Global.getCloudClient();
        photoUploadMgr = new UploadManager(this, Global.APP_ID_V2STR, Const.FileType.Photo, null);

        dialog = CustomProgressDialog.createDialog(this);
        dialog.setCancelable(false);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_CAMERA:
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 授权成功
                    doTakePhoto();
                } else {
                    // 授权失败
                    Toast.makeText(this, "您未授权应用访问摄像头", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    /**
     * 拍照
     */
    public void takePhoto(View view) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.CAMERA)) {
            } else {
                ActivityCompat.requestPermissions(this,  new String[]{Manifest.permission.CAMERA},
                        MY_PERMISSIONS_REQUEST_CAMERA);
            }
        } else {
            doTakePhoto();
        }
    }

    private void doTakePhoto() {
        Intent intent = new Intent();
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        photoPath = Global.generateTempPhotoPath();
        File file = new File(photoPath);
        file.deleteOnExit();
        file.getParentFile().mkdirs();
        Uri fileUri = Uri.fromFile(file);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        startActivityForResult(intent, RESULT_TAKE_PHOTO);
    }

    /**
     * 验证人员信息
     */
    public void verifyPerson(View view) {
        dialog.show();
        showToast("使用登录身份证号开始验证人员信息");
        if(StringUtils.isNotBlank(photoPath)) {
            Global.pool.submit(new Runnable() {
                @Override
                public void run() {
                    try{
                        JSONObject result = qcSDK.FaceVerify(photoPath, Global.cardId);
                        Log.e("qcface", "face verify:" + result.toString());
                        int errorCode = result.optInt("errorcode");
                        Message msg = new Message();
                        if(errorCode == 0) {
                            // 成功，输出结果
                            msg.what = MSG_VERIFY_FACE_SUCCESS;
                            msg.obj = formatVerifyResult(result);
                            handler.sendMessage(msg);
                        } else if(errorCode == Global.ERROR_PERSON_NOT_EXISTED) {
                            // 用户不存在，提示新建用户
                            handler.sendEmptyMessage(MSG_PERSON_NOT_EXIST);
                        } else {
                            // 操作失败，请重试
                            handler.sendEmptyMessage(MSG_COMMON_ERROR);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        // 通用失败，请重试
                        handler.sendEmptyMessage(MSG_COMMON_ERROR);
                    }
                }
            });
        } else {
            showToast("请先拍照");
            dialog.hide();
        }
    }

    /**
     * 身份证，使用android SDK
     */
    public void verifyIdcardAndroid(View view) {
        dialog.show();
        showToast("使用图片和登录身份证号直接匹配身份证照片，需要先上传图片，然后再进行匹配");
        if(StringUtils.isNotBlank(photoPath)) {
            PhotoUploadTask task = new PhotoUploadTask(photoPath, new IUploadTaskListener() {
                @Override
                public void onUploadSucceed(FileInfo fileInfo) {
                    Log.e("qcface", "upload success. url: " + fileInfo.url);

                    Message msg = new Message();
                    msg.what = MSG_IDCARD_UPLOAD_SUCCESS;
                    msg.obj = fileInfo.url;
                    handler.sendMessage(msg);
                }

                @Override
                public void onUploadFailed(int code, String msg) {
                    Log.e("qcface", "upload failed. code:" + code + ", msg: " + msg);
                }

                @Override
                public void onUploadProgress(long totalSize, long sendSize) {

                }

                @Override
                public void onUploadStateChange(ITask.TaskState taskState) {

                }
            });
            task.setBucket(Global.BUCKET);
            task.setFileId("idcard" + "/" + Global.cardId + "/" + System.currentTimeMillis() + ".jpg");
            long expired = System.currentTimeMillis() / 1000 + 2592000;
            String sign = pc.getSign(expired);
            task.setAuth(sign);
            photoUploadMgr.upload(task);
        } else {
            showToast("请先拍照");
            dialog.hide();
        }
    }

    private void doIdcardVerifyAndroid(final String fileURI) {
        Global.pool.submit(new Runnable() {
            @Override
            public void run() {
                try{
                    long expired = System.currentTimeMillis() / 1000 + 2592000;
                    String sign = pc.getSign(expired);
                    HashMap<String, String> header = new HashMap<>();
                    header.put("Authorization", sign);
                    header.put("Host", "service.image.myqcloud.com");
                    header.put("Content-Type", "application/json");

                    JSONObject params = new JSONObject();
                    params.put("appid", Global.APP_ID_V2STR);
                    params.put("bucket", Global.BUCKET);
                    params.put("idcard_number", Global.cardId);
                    params.put("idcard_name", Global.name);
                    params.put("url", fileURI);
                    String result = cc.post(Global.URI_IDCARDCOMPARE, header, null, params.toString().getBytes());
                    Log.e("qcface", "verify idcard:" + result);
                    JSONObject resultObj = new JSONObject(result);
                    if(resultObj.optInt("code", -1) == 0) {
                        // 成功
                        Message msg = new Message();
                        msg.what = MSG_IDCARD_VERIFY_SUCCESS;
                        msg.obj = formatVerifyIdcardResult(resultObj);
                        handler.sendMessage(msg);
                    } else {
                        handler.sendEmptyMessage(MSG_IDCARD_VERIFY_FAIL);
                    }
                } catch(Exception e) {
                    e.printStackTrace();
                    handler.sendEmptyMessage(MSG_COMMON_ERROR);
                }
            }
        });
    }


    /**
     * 身份证
     */
    @Deprecated
    public void verifyIdcard(View view) {
        dialog.show();
        showToast("使用图片和登录身份证号直接匹配身份证照片，需要先上传图片，然后再进行匹配");
        if(StringUtils.isNotBlank(photoPath)) {
            Global.pool.submit(new Runnable() {
                @Override
                public void run() {
                    uploadResult = pc.upload(photoPath, "idcard" + "/" + Global.cardId + "/" + System.currentTimeMillis() + ".jpg");
                    if(uploadResult != null) {
                        Message msg = new Message();
                        msg.what = MSG_IDCARD_UPLOAD_SUCCESS;
                        msg.obj = uploadResult.downloadUrl;
                        handler.sendMessage(msg);

                        // 上传图片成功，开始匹配过程
                        doIdcardVerify();
                    } else {
                        handler.sendEmptyMessage(MSG_IDCARD_UPLOAD_FAIL);
                    }
                }
            });
        } else {
            showToast("请先拍照");
            dialog.hide();
        }
    }

    @Deprecated
    private void doIdcardVerify() {
        if(uploadResult == null) {
            return;
        }

        try{
            long expired = System.currentTimeMillis() / 1000 + 2592000;
            String sign = pc.getSign(expired);
            HashMap<String, String> header = new HashMap<>();
            header.put("Authorization", sign);
            header.put("Host", "service.image.myqcloud.com");
            header.put("Content-Type", "application/json");

            JSONObject params = new JSONObject();
            params.put("appid", Global.APP_ID_V2STR);
            params.put("bucket", Global.BUCKET);
            params.put("idcard_number", Global.cardId);
            params.put("idcard_name", Global.name);
            params.put("url", uploadResult.downloadUrl);
            String result = cc.post(Global.URI_IDCARDCOMPARE, header, null, params.toString().getBytes());

            JSONObject resultObj = new JSONObject(result);
            if(resultObj.optInt("code", -1) == 0) {
                // 成功
                Message msg = new Message();
                msg.what = MSG_IDCARD_VERIFY_SUCCESS;
                msg.obj = formatVerifyIdcardResult(resultObj);
                handler.sendMessage(msg);
            } else {
                handler.sendEmptyMessage(MSG_IDCARD_VERIFY_FAIL);
            }
        } catch(Exception e) {
            e.printStackTrace();
            handler.sendEmptyMessage(MSG_COMMON_ERROR);
        }
    }

    private static final int MSG_COMMON_ERROR = 0;
    private static final int MSG_VERIFY_FACE_SUCCESS = 1;
    private static final int MSG_PERSON_NOT_EXIST = 2;
    private static final int MSG_IDCARD_UPLOAD_SUCCESS = 3;
    private static final int MSG_IDCARD_UPLOAD_FAIL = 4;
    private static final int MSG_IDCARD_VERIFY_SUCCESS = 5;
    private static final int MSG_IDCARD_VERIFY_FAIL = 6;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_COMMON_ERROR:
                    showToast("操作异常，请重试！");
                    dialog.hide();
                    break;
                case MSG_VERIFY_FACE_SUCCESS:
                    showToast("识别成功！" + msg.obj);
                    dialog.hide();
                    break;
                case MSG_PERSON_NOT_EXIST:
                    showToast("用户不存在，请先使用导入功能新建用户。");
                    dialog.hide();
                    break;
                case MSG_IDCARD_UPLOAD_SUCCESS:
                    showToast("上传用户图片成功");
                    doIdcardVerifyAndroid((String) msg.obj);
                    break;
                case MSG_IDCARD_UPLOAD_FAIL:
                    showToast("上传用户图片失败");
                    dialog.hide();
                    break;
                case MSG_IDCARD_VERIFY_SUCCESS:
                    showToast("对比身份证图片成功！" + msg.obj);
                    dialog.hide();
                    break;
                case MSG_IDCARD_VERIFY_FAIL:
                    showToast("对比身份证图片失败！" );
                    dialog.hide();
                    break;
            }
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // 拍摄照片
        if(requestCode == RESULT_TAKE_PHOTO && resultCode == RESULT_OK) {
            File file = new File(photoPath);
            if(file.exists()) {
                File destFile = new File(Global.generateTempPhotoPath());
                FileUtil.compressImage(file, destFile, 70);

                photoPath = destFile.getAbsolutePath();
                ivPhoto.setImageBitmap(BitmapFactory.decodeFile(photoPath));
            }
        }
    }

    private void showToast(String msg) {
        String nowTimeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        tvOutput.append(nowTimeStr + " -- " + msg + "\n");
    }

    private String formatVerifyResult(JSONObject result) {
        return String.format("系统认为该图片%s身份证号%s的用户，相似度为%.2f",
                (result.optBoolean("ismatch", false) ? "是" : "不是"),
                Global.cardId,
                result.optDouble("confidence", 0.00d)) + "%";
    }

    private String formatVerifyIdcardResult(JSONObject result) {
        return String.format("该图片同身份证号%s用户的身份证对比相似度为%.1d",
                Global.cardId,
                result.optJSONObject("data").optDouble("similarity")) + "%";
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(dialog != null) {
            dialog.dismiss();
        }
    }
}
